package com.szeldon.declatest.eval.plugins;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.szeldon.declatest.eval.ConditionReturnValue;
import com.szeldon.declatest.eval.ScenarioPartEvaluator;
import com.szeldon.declatest.eval.exceptions.EvaluationException;
import com.szeldon.declatest.exec.TestSuiteExecHistory;
import com.szeldon.declatest.exec.events.dostep.jms.JmsMessageReceivedExecEvent;
import com.szeldon.utils.FileUtils;

/**
 * Unit tests for {@link XPathEvaluatorPlugin} class.
 * 
 * @author szeldon
 * 
 */
public class XPathEvaluatorPluginTest {
    private XPathEvaluatorPlugin plugin;
    private static final String XPATH_TEST_FILES_DIRECTORY = "tests-res/com/szeldon/declatest/eval/plugins/";

    @BeforeTest
    public void beforeTest() {
        plugin = new XPathEvaluatorPlugin();
    }

    @Test
    public void testEvaluateProperXPath1() throws EvaluationException, IOException {
        String evaluated = plugin.evaluateValue(null, "//RootTag/ChildTag@"
                + readTestFile(XPATH_TEST_FILES_DIRECTORY + "xpath-plugin-01.xml"), null, null);
        Assert.assertEquals(evaluated, "ChildTagValue");
    }

    @Test
    public void testEvaluateProperXPath2() throws EvaluationException, IOException {
        String evaluated = plugin.evaluateValue(null, "count(//RootTag/ChildTag)@"
                + readTestFile(XPATH_TEST_FILES_DIRECTORY + "xpath-plugin-01.xml"), null, null);
        Assert.assertEquals(evaluated, "1");
    }

    @Test
    public void testEvaluateProperXPath3() throws EvaluationException, IOException {
        String evaluated = plugin.evaluateValue(null, "count(//RootTag/BadChildTag)@"
                + readTestFile(XPATH_TEST_FILES_DIRECTORY + "xpath-plugin-01.xml"), null, null);
        Assert.assertEquals(evaluated, "0");
    }

    @Test
    public void testEvaluateProperXPathWithNoValue1() throws EvaluationException, IOException {
        String evaluated = plugin.evaluateValue(null, "//RootTag/BadChildTag@"
                + readTestFile(XPATH_TEST_FILES_DIRECTORY + "xpath-plugin-01.xml"), null, null);
        Assert.assertEquals(evaluated, "");
    }

    @Test
    public void testProperXPathOnResponse() throws EvaluationException, IOException {
        ScenarioPartEvaluator evaluator = new ScenarioPartEvaluator();
        evaluator.addPlugin(new XPathEvaluatorPlugin());
        evaluator.addPlugin(new DefaultEvaluatorPlugin());
        TestSuiteExecHistory history = new TestSuiteExecHistory("testsuiteid");
        history.addExecEvent(new JmsMessageReceivedExecEvent("scenarioId", "event description", new Date(), "stepId",
                "stepDescription", "stepEndpointId", "stepRequestPath", "endpointDescription", "endpointUrl",
                "endpointSettingsId", "queue", "queueName", FileUtils
                        .readFileContent("tests-res/com/szeldon/declatest/eval/scenario-response-01.xml")));

        ConditionReturnValue returnValue = evaluator.evaluateCondition(new Properties(), null,
                "${xpath#//RootTag/ChildTag[1]@${response@stepId@step}}", "equals", "ChildTagValue", history);
        Assert.assertEquals(returnValue.getEvaluatedLeft(), "ChildTagValue");
        Assert.assertEquals(returnValue.getEvaluatedRight(), "ChildTagValue");
        Assert.assertEquals(returnValue.isEvaluatedTrue(), true);
    }

    /**
     * Reads in file with provided filename.
     * 
     * @param filename
     * @return
     * @throws IOException
     */
    private String readTestFile(String filename) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        reader.close();
        return builder.toString();
    }
}
